﻿using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.Linq;

namespace CRM.Database.Model
{
    /// <summary>
    /// Коллекция пользователей
    /// </summary>
    public class UsersCollection : AbstractCollection
    {
        /// <summary>
        /// Статическая коллекция
        /// </summary>
        protected static List<Users> _list;

        /// <summary>
        /// Список пользователей
        /// </summary>
        public List<Users> UsersList
        {
            get
            {
                //return Entities.Users.ToList();
                if (_list == null)
                    try
                    {
                        _list = Entities.Users.OrderBy(c => c.UserFullNameRu).ToList();
                    }
                    catch
                    {
                        throw new Exception("Возникла ошибка");
                    }
                return _list;
            }
        }

        /// <summary>
        /// Менеджеры
        /// </summary>
        public List<Users> Managers
        {
            get { return UsersList.Where(user => user.IsInRoleType(2)).ToList(); }
        }


        /// <summary>
        /// Техники
        /// </summary>
        public List<Users> Technics
        {
            get { return UsersList.Where(user => user.IsInRoleType(3)).ToList(); }
        }



        public object GetItemByName(string userName)
        {
            userName = userName.Replace("RU\\", "");
            return base.GetItemByName(userName);
        }

        /// <summary>
        /// Обнуление статической коллекции
        /// </summary>
        protected override void SetStaticListToNULL()
        {
            _list = null;
        }

        /// <summary>
        /// Получить пользователя по Id
        /// </summary>
        /// <param name="idUser">Id пользователя</param>
        /// <returns>пользователь</returns>
        public Users GetUserbyId(int idUser)
        {
            return GetItemById(idUser) as Users;
        }


        /// <summary>
        /// Получение пользователя из базы по идентификатору
        /// </summary>
        /// <param name="idUser">Идентификатор</param>
        /// <returns>Пользователь</returns>
        public Users GetUserByIdFromEntities(int idUser)
        {
            foreach (Users user in Entities.Users)
            {
                if (user.IdUser == idUser)
                    return user;
            }
            return null;
        }


        /// <summary>
        /// Получение имени пользователя по логину
        /// </summary>
        /// <param name="login">Логин</param>
        /// <returns>Имя пользователя</returns>
        public Users GetUserByLogin(string login)
        {
            if (string.IsNullOrEmpty(login))
                return null;
            if (login.Length < 6)
                return null;
            login = login.Replace("RU\\", "");

            //Users usr = Entities.Users.FirstOrDefault(c => c.UserLogin == login);
            Users usr = UsersList.FirstOrDefault(c => c.UserLogin == login);
            if (usr != null)
                return usr;
            //  usr = Entities.Users.FirstOrDefault(c => c.UserLogin.ToUpper() == login.ToUpper());
            usr = UsersList.FirstOrDefault(c => c.UserLogin.ToUpper() == login.ToUpper());
            //if(usr==null)
            //    usr = GetUserNameFromADByLogin(login);
            return usr;
        }

        /// <summary>
        /// Получение списка пользователей по типу роли
        /// </summary>
        /// <param name="idRoleType"></param>
        public List<Users> GetUsersByIdRoleType(int idRoleType)
        {
            var result = new List<Users>();

            foreach (Users user in UsersList)
            {
                foreach (Roles role in user.Roles)
                {
                    if (role != null)
                        if (role.IdRolesType == idRoleType)
                            if (!result.Contains(user))
                                result.Add(user);
                }
            }

            return result.OrderBy(p => p.LocalizedFullName).ToList();
        }

        /// <summary>
        /// Получение пользователя из AD
        /// </summary>
        /// <param name="login">Логин</param>
        /// <returns>Пользователь</returns>
        public static Users GetUserNameFromADByLogin(string login)
        {
            var result = new Users();
            var col = new UsersCollection();
            login = login.Replace(@"RU\", "");
            var ds = new DirectorySearcher();
            ds.Filter = "(objectCategory=user)";
            SearchResultCollection sr = ds.FindAll();
            foreach (SearchResult s in sr)
            {
                foreach (object o in s.Properties["samaccountname"])
                {
                    if (o.ToString() == login)
                    {
                        try
                        {
                            result.UserFullNameEn = s.Properties["displayname"][0] as string; //descriptio
                            result.UserFullNameRu = s.Properties["description"][0] as string;
                            result.UserEmail = s.Properties["mail"][0] as string;
                            result.UserLogin = login;

                            col.Add(result, "Max");

                            return result;
                        }
                        catch
                        {
                        }
                    }
                }
            }

            return null;
        }

        #region Implementation of IAddDeleteUpdatecs

        /// <summary>
        /// Обновление элемента в коллекции
        /// </summary>
        /// <param name="item">Новый элемент</param>
        /// <param name="userLogin"></param>
        /// <returns>Результат операции</returns>
        public new bool Update(object item, string userLogin)
        {
            var newUser = (Users) item;

            if (newUser == null)
                return false;

            Users user4Update = GetUserByIdFromEntities(newUser.IdUser);
            if (user4Update == null)
                return false;

            if (!string.IsNullOrEmpty(newUser.UserEmail))
                user4Update.UserEmail = newUser.UserEmail;


            if (!string.IsNullOrEmpty(newUser.UserFullNameEn))
                user4Update.UserFullNameEn = newUser.UserFullNameEn;

            if (!string.IsNullOrEmpty(newUser.UserFullNameRu))
                user4Update.UserFullNameRu = newUser.UserFullNameRu;

            return base.Update(user4Update, userLogin);
        }

        #endregion

        #region Implementation of IGetItem

        /// <summary>
        /// Получение списка элементов
        /// </summary>
        /// <returns>Список элементов</returns>
        public override List<object> GetList()
        {
            return new List<object>(UsersList);
        }

        /// <summary>
        /// Получение типа текущего элемента
        /// </summary>
        /// <returns></returns>
        protected override Type GetItemType()
        {
            return typeof (Users);
        }

        /// <summary>
        /// Получение статического списка для хранения объектов
        /// </summary>
        /// <returns></returns>
        public override object GetStaticCollection()
        {
            return _list;
        }

        /// <summary>
        /// Получение элемента из коллекции по идентификатору
        /// </summary>
        /// <param name="itemId">Идентификатор</param>
        /// <returns>Элемент</returns>
        public override object GetItemById(int itemId)
        {
            return Entities.Users.Find(itemId);
        }

        #endregion
    }
}